/**
 * 初始集合有两个数X和Y，两种操作：
 * 1. 从集合中选两个元素a和b，将gcd(a, b)放入集合
 * 2. 从集合中选两个元素a和b，将a+b放入集合
 * 集合是多重集合，a和b不同，但值可以相等
 * 要求200个操作后要得到lcm(X, Y)
 * 
 * 首先求 g = gcd(X, Y)，并将集合改为{x = X/g, y = Y/g}
 * 此时保证gcd(x, y) == 1，原问题就变为从{x, y}要得到 x * y
 * 首先用两次操作1，于是将2个1放入了集合
 * 然后将Fib数依次放入集合。
 * 根据Zeckendorf定理，任意整数都能表示为不连续的Fib数之和，因此可以达成目标
 */
#include <bits/stdc++.h>
using namespace std;

#include <bits/extc++.h>
using namespace __gnu_pbds;

using llt = long long;

llt X, Y;

void proc(){
    if(X % Y == 0 or Y % X == 0) return (void)(cout << "0\n");

    vector<tuple<int, llt, llt>> ans;

    llt g = __gcd(X, Y);
    llt x = X / g, y = Y / g;
    llt target = x * y;
    
    ans.emplace_back(1, x, y);
    ans.emplace_back(1, x, y); // 此时集合里有2个1

    vector<llt> f;
    f.emplace_back(1);
    f.emplace_back(1);

    llt a = 1, b = 1;
    while(1){
        auto c = a + b;
        if(c > target) break;

        ans.emplace_back(2, a, b);
        a = b, b = c;
        f.emplace_back(c);
    }

    function<void(llt)> __dfs = [&](llt t){
        auto pp = equal_range(f.begin(), f.end(), t);
        if(pp.first != pp.second){
            return;
        }

        assert(pp.first != f.begin());
        auto it = pp.first - 1;
        __dfs(t - *it);
        ans.emplace_back(2, t - *it, *it);
        return;
    };

    __dfs(target);

    assert(ans.size() <= 200);
    cout << ans.size() << "\n";
    for(auto [a, b, c] : ans){
        cout << a << " " << b * g << " " << c * g << "\n";
    }
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
    int nofkase = 1;
    cin >> nofkase;
    while(nofkase--){
        cin >> X >> Y;
        proc();
    }
    return 0;
}